
// 迭代器模式
// 提供一种方法顺序访问一个聚合对象中的各个元素，而又不暴露该对象的内部表示。

#include <vector>
#include <iostream>
using namespace std;


// 前向声明，因为两个类互相引用
class Iterator;
class RemoteControl;
class Television;
class Aggregate;

// 抽象聚合类 Aggregate
class Aggregate
{
public:
	Aggregate(){}
	virtual Iterator* createIterator() = 0;
};

// 具体聚合类 Television
class Television :public Aggregate
{
public:
	Television()=default;
	Television(vector<string> iChannelList){
		this->channelList = iChannelList;
	}
	// 实现创建迭代器
	Iterator* createIterator();
	// 获取总的频道数目
	int getTotalChannelNum(){
		return channelList.size();
	}
	void play(int i){
		printf("现在播放：%s……\n", channelList[i].c_str());
	}
private:
	vector<string> channelList;
};

// 抽象迭代器
class Iterator
{
public:
	Iterator(){}
	// 声明抽象遍历方法
	virtual void first() = 0;
	virtual void last() = 0;
	virtual void next() = 0;
	virtual void previous() = 0;
	virtual bool hasNext() = 0;
	virtual bool hasPrevious() = 0;
	virtual void currentChannel() = 0;
};

// 遥控器：具体迭代器
class RemoteControl :public Iterator
{
public:
	RemoteControl(){}
	void setTV(Television *iTv){
		this->tv = iTv;
		cursor = -1;
		totalNum = tv->getTotalChannelNum();
	}
	// 实现各个遍历方法
	void first(){
		cursor = 0;
	}
	void last(){
		cursor = totalNum - 1;
	}
	void next(){
		cursor++;
	}
	void previous(){
		cursor--;
	}
	bool hasNext(){
		return !(cursor == totalNum);
	}
	bool hasPrevious(){
		return !(cursor == -1);
	}
	void currentChannel(){
		tv->play(cursor);
	}
private:
	// 游标
	int cursor;
	// 总的频道数目
	int totalNum;
	// 电视
	Television* tv;
};

Iterator* Television::createIterator(){
	// 因为有 new RemoteControl 所以，必须在函数定义之前，定义 RemoteControl类。
	// 就算最开始写 class RemoteControl; 也没用
	RemoteControl *it = new RemoteControl();
	it->setTV(this);
	return (Iterator*)it;
}


int main()
{
	vector<string> channelList = { "新闻频道", "财经频道", "体育频道", "电影频道", "音乐频道", "农业频道", "四川卫视", "成都卫视" };
	// 创建电视
	Television *tv = new Television(channelList);
	// 创建遥控器
	Iterator *remoteControl = tv->createIterator();

	// 顺序遍历
	printf("顺序遍历:\n");
	remoteControl->first();
	// 遍历电视所有频道
	while (remoteControl->hasNext()){
		remoteControl->currentChannel();
		remoteControl->next();
	}

	printf("\n\n");

	// 逆序遍历
	printf("逆序遍历:\n");
	remoteControl->last();
	// 遍历电视所有频道
	while (remoteControl->hasPrevious()){
		remoteControl->currentChannel();
		remoteControl->previous();
	}

	printf("\n\n");
	system("pause");
	return 0;
}



